# -*- coding: utf-8 -*-
import os
from urllib.parse import quote

from django.http import HttpResponse
from openpyxl.utils import get_column_letter
from openpyxl.workbook import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
from openpyxl.styles import Font, colors, Alignment, PatternFill
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from rest_framework.validators import UniqueTogetherValidator
from xmind2testcase.utils import get_xmind_testcase_list
from xmind2testcase.zentao import gen_a_testcase_row

from dvadmin.system.models import FileList
from dvadmin.design.models import XMind, NodeTypes, NodesHierarchy
from dvadmin.design.views.hierarchy import NodesHierarchySerializer
from dvadmin.utils.json_response import DetailResponse, ErrorResponse, SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet
from dvadmin.system.views.file_list import FileSerializer

class XMindSerializer(CustomModelSerializer):
    """
    思维导图-序列化器
    """

    class Meta:
        model = XMind
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=XMind.objects.all(),
                fields=['name', 'note', 'status'],
                message="名字、备注、状态必须唯一"
            )
        ]


class XMindViewSet(CustomModelViewSet):
    """
    思维导图 接口
    list:查询
    save:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = XMind.objects.all()
    serializer_class = XMindSerializer

    def create(self, request, *args, **kwargs):

        name = request.data.get('name')
        node_type = request.data.get('node_type')
        note = request.data.get('note')

        instance = NodeTypes.objects.filter(description='testmodel').first()
        if instance is None:
            return ErrorResponse(msg="查询出错")

        parent = NodesHierarchy.objects.filter(name=name, node_order=0, node_type=instance, parent=None).first()
        if parent is not None:
            return ErrorResponse(msg="名称已存在")

        # Hierarchy新增1条testmodel，作为根节点
        data_hier = {"name": name, "node_order": 0, "node_type": instance.id, "parent": None}
        serializer = NodesHierarchySerializer(data=data_hier, request=request)
        serializer.is_valid(raise_exception=True)
        parent = serializer.save()

        instance = NodeTypes.objects.filter(description=node_type).first()
        if instance is None:
            return ErrorResponse(msg="查询出错")

        # Hierarchy新增1条model detail，作为枝节点
        data_hier = {"name": name, "node_order": 0, "node_type": instance.id, "parent": parent.id}
        serializer = NodesHierarchySerializer(data=data_hier, request=request)
        serializer.is_valid(raise_exception=True)
        hierarchy = serializer.save()

        serializer = FileSerializer(data=request.data, request=request)
        serializer.is_valid(raise_exception=True)
        file_list = serializer.save()

        data_xmind = {"name": name, "note": note, "status": True, "file_list_id": file_list.id , "hierarchy": hierarchy.id}
        serializer = XMindSerializer(data=data_xmind, request=request)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return DetailResponse(msg="成功")

    def list(self, request, *args, **kwargs):

        is_superuser = request.user.is_superuser
        if is_superuser:
            queryset = XMind.objects.all().values_list("hierarchy")
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            queryset = XMind.objects.filter(dept_belong_id__in=dept_list).values_list("hierarchy")

        queryset = NodesHierarchy.objects.filter(id__in=queryset).values_list("parent")
        queryset = NodesHierarchy.objects.filter(id__in=queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = NodesHierarchySerializer(page, many=True, request=request)
            return self.get_paginated_response(serializer.data)
        serializer = NodesHierarchySerializer(queryset, many=True, request=request)
        return SuccessResponse(data=serializer.data, msg="成功")

    def retrieve(self, request, *args, **kwargs):

        pid = kwargs.get('pk')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        filelist = XMind.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()

        data = {"id": instance.id, "name": instance.name, "file_url": queryset.file_url, "file_name": queryset.name, "file_id": queryset.id, "file_size": queryset.size}
        return DetailResponse(data=data, msg="成功")

    @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
    def gen(self, request, *args, **kwargs):
        """思维导图 根据测试模型生成测试场景  """

        pid = request.query_params.get('id')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        filelist = XMind.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()
        here = os.path.abspath(os.getcwd())
        full_path = os.path.join(here, queryset.file_url)
        res = get_xmind_testcase_list(full_path)

        data = {"id": instance.id, "name": instance.name}
        page = self.paginate_queryset(res)
        if page is not None:
            data["testsuite"] = page
            return self.get_paginated_response(data)
        data = {"id": instance.id, "name": instance.name, "testsuite": res}
        return DetailResponse(data=data, msg="成功")

    @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
    def export(self, request, *args, **kwargs):
        """思维导图 导出模型和场景 """

        pid = request.query_params.get('id')
        is_superuser = request.user.is_superuser
        if is_superuser:
            instance = NodesHierarchy.objects.filter(id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(parent_id=pid)
        else:
            dept_list = request.user.role.values_list('dept', flat=True)
            instance = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, id=pid).first()
            hierarchy = NodesHierarchy.objects.filter(dept_belong_id__in=dept_list, parent_id=pid)
        response = HttpResponse(content_type="application/msexcel")
        response["Access-Control-Expose-Headers"] = f"Content-Disposition"
        response["content-disposition"] = f'attachment;filename={quote(str(f"导出{instance.name}.xlsx"))}'
        wb = Workbook()
        ws2 = wb.create_sheet(index=0, title='测试场景')

        filelist = XMind.objects.filter(status=1, hierarchy__in=hierarchy).values('file_list_id').first()
        queryset = FileList.objects.filter(id=filelist['file_list_id']).first()
        here = os.path.abspath(os.getcwd())
        full_path = os.path.join(here, queryset.file_url)
        data = get_xmind_testcase_list(full_path)

        title2 = ['序号', '测试目的', "所属模块", "用例标题", "前置条件", "步骤", "预期", "关键词", "优先级", "用例类型", "适用阶段"]
        row2 = get_column_letter(len(title2))
        column = 1
        ws2.append(title2)
        for index, testcase in enumerate(data):
            results = gen_a_testcase_row(testcase)
            results_list = []
            for h_index, val in enumerate(results):
                if val is None or val == "":
                    results_list.append("")
                else:
                    results_list.append(val)
            ws2.append([index + 1, instance.name, *results_list])
            column += 1
        # 　更新列宽
        for index in range(len(title2)):
            ws2.column_dimensions[get_column_letter(index + 2)].width = 30
        tab2 = Table(displayName="Table2", ref=f"A1:{row2}{column}")  # 名称管理器
        style = TableStyleInfo(
            name="TableStyleLight11",
            showFirstColumn=True,
            showLastColumn=False,
            showRowStripes=True,
            showColumnStripes=True,
        )

        tab2.tableStyleInfo = style
        ws2.add_table(tab2)
        wb.save(response)
        return response

